﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Web;
using System.Configuration;
using CFCA.Payment.Api;
using System.Transactions;
/// <summary>
///PaymentManager 的说明:
///CFCA接口的支付类
/// </summary>
public class PaymentManager
{
    protected string institutionID = ConfigurationManager.AppSettings["Pay_InstitutionID"];//value="000259"
    protected string notificationURL = ConfigurationManager.AppSettings["Pay_NotificationURL"];//回调URL//http://www.haiji.com/Payment/ReceiveNotice
    protected string AccountName = "陈建波";//网站收款账户名
    
    /// <summary>
    /// 订单支付前的准备
    /// </summary>
    /// <param name="orderID">订单ID</param>
    /// <param name="orderNo">订单号</param>
    /// <param name="bankID">付款银行ID</param>
    /// <param name="accountType">付款账户类型（11=个人账户，12=企业账户）</param>
    /// <param name="TotalValue">订单总金额</param>
    /// <param name="UserID">付款方UserID</param>
    /// <param name="message">提供给相应付款银行的验证消息</param>
    /// <param name="signature">提供给相应付款银行的签名信息</param>
    /// <param name="action">相应付款银行的接口地址</param>
    /// <param name="error"></param>
    /// <returns>是否可以跳转到实际的付款银行</returns>
    public bool Pay(long orderID, string orderNo, string bankID, int accountType, decimal TotalValue, long UserID, out string message, out string signature, out string action, out string error)
    {
        message = "";
        signature = "";
        action = "";
        error = "";
        bool flag = true;
        #region 事务开始
        TransactionOptions transactionOption = new TransactionOptions();
        transactionOption.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
        transactionOption.Timeout = new TimeSpan(0, 0, 60);
        using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required, transactionOption))
        {
            try
            {
                string serialNumber = CreateSerialNumber(orderID, orderNo);
                long amount = Convert.ToInt64(TotalValue * 100);//订单总金额换算成分
                string payerID = UserID.ToString();
                string payerName = "";//如果支付时提供了付款者帐户名称，则退款时收款人帐户名称只能是支付时提供的付款者帐户名称
                string remark = UserID + "(" + orderNo + ")-服务费";

              
                Model.TradeLog tradeLog = BLL.TradeLog.GetBySerialNumber(serialNumber);
                if (tradeLog == null)
                {
                    tradeLog = new Model.TradeLog();
                    tradeLog.OrderID = orderID;
                    tradeLog.Type = Model.RRBEnum.OrderTradeType.支付.GetHashCode();
                    tradeLog.SerialNumber = serialNumber;
                    tradeLog.AddTime = DateTime.Now;
                    if (BLL.TradeLog.Add(tradeLog) <= 0)
                    {
                        throw new Exception("添加支付交易日志出错");
                    }
                }
                else
                {
                    tradeLog.ModTime = DateTime.Now;
                    if (BLL.TradeLog.Update(tradeLog)<0)
                    {
                        throw new Exception("修改支付交易日志出错");
                    }
                }
                ///支付
                Tx1311Request tx1311Request = new Tx1311Request();
                tx1311Request.setInstitutionID(institutionID);
                tx1311Request.setOrderNo(orderNo);
                tx1311Request.setPaymentNo(serialNumber);
                tx1311Request.setAmount(amount);
                tx1311Request.setPayerID(payerID);
                tx1311Request.setPayerName(payerName);
                tx1311Request.setRemark(remark);
                tx1311Request.setNotificationURL(notificationURL);
                tx1311Request.setBankID(bankID);
                tx1311Request.setAccountType(accountType);
                tx1311Request.addPayee(AccountName);
                tx1311Request.process();
                message = tx1311Request.getRequestMessage();
                signature = tx1311Request.getRequestSignature();
                action = PaymentEnvironment.PaymentURL;

                ts.Complete();
            }
            catch (Exception ex)
            {
                flag = false;
                error = ex.Message;
            }
            finally
            {
                ts.Dispose();
            }
        }
        #endregion
        return flag;
    }
    /// <summary>
    /// 生成交易流水号
    /// </summary>
    /// <param name="orderID"></param>
    /// <param name="orderNo"></param>
    /// <returns></returns>
    public string CreateSerialNumber(long orderID, string orderNo)
    {
        string rtn = "-1";
        Model.TradeLog tradeLog = BLL.TradeLog.GetLastByOrderID(orderID);
        if (tradeLog != null)
        {
            string oldSerialNumber = tradeLog.SerialNumber;
            if (oldSerialNumber.Length == 22)
            {
                string lastChar = tradeLog.SerialNumber.Substring(21);
                int lastNum = LetterToInt(lastChar);
                if (lastNum != -1)
                {
                    int newNum = lastNum + 1;
                    string newChar = IntToLetter(newNum);
                    if (newChar != "-1")
                    {
                        rtn = orderNo + newChar;
                    }
                }
            }
        }
        else
        {
            if (orderNo.Length == 21)
            {
                rtn = orderNo + "1";
            }
        }
        return rtn;
    }
    /// <summary>
    /// 将10到35的整数转换成小写字母
    /// </summary>
    /// <param name="number"></param>
    /// <returns>-1表示转换失败</returns>
    public static string IntToLetter(int number)
    {
        switch (number)
        {
            case 0: return "0";
            case 1: return "1";
            case 2: return "2";
            case 3: return "3";
            case 4: return "4";
            case 5: return "5";
            case 6: return "6";
            case 7: return "7";
            case 8: return "8";
            case 9: return "9";
            case 10: return "a";
            case 11: return "b";
            case 12: return "c";
            case 13: return "d";
            case 14: return "e";
            case 15: return "f";
            case 16: return "g";
            case 17: return "h";
            case 18: return "i";
            case 19: return "j";
            case 20: return "k";
            case 21: return "l";
            case 22: return "m";
            case 23: return "n";
            case 24: return "o";
            case 25: return "p";
            case 26: return "q";
            case 27: return "r";
            case 28: return "s";
            case 29: return "t";
            case 30: return "u";
            case 31: return "v";
            case 32: return "w";
            case 33: return "x";
            case 34: return "y";
            case 35: return "z";
            default: return "-1";
        }
    }
    /// <summary>
    /// 将26个小写字母转换成10到35的整数
    /// </summary>
    /// <param name="letter"></param>
    /// <returns>-1表示转换失败</returns>
    public static int LetterToInt(string letter)
    {
        switch (letter)
        {
            case "0": return 0;
            case "1": return 1;
            case "2": return 2;
            case "3": return 3;
            case "4": return 4;
            case "5": return 5;
            case "6": return 6;
            case "7": return 7;
            case "8": return 8;
            case "9": return 9;
            case "a": return 10;
            case "b": return 11;
            case "c": return 12;
            case "d": return 13;
            case "e": return 14;
            case "f": return 15;
            case "g": return 16;
            case "h": return 17;
            case "i": return 18;
            case "j": return 19;
            case "k": return 20;
            case "l": return 21;
            case "m": return 22;
            case "n": return 23;
            case "o": return 24;
            case "p": return 25;
            case "q": return 26;
            case "r": return 27;
            case "s": return 28;
            case "t": return 29;
            case "u": return 30;
            case "v": return 31;
            case "w": return 32;
            case "x": return 33;
            case "y": return 34;
            case "z": return 35;
            default: return -1;
        }
    }

    /// <summary>
    /// 订单支付查询
    /// </summary>
    /// <param name="orderID"></param>
    /// <param name="Amount"></param>
    /// <param name="BankNotificationTime"></param>
    /// <returns></returns>
    public bool PayQuery(long orderID, out long Amount, out string NotificationTime)
    {
        Amount = 0;
        NotificationTime = "";
        bool flag = false;

        if (orderID>0)
        {            
            Model.TradeLog tradeLog = BLL.TradeLog.GetEffectivePay(orderID);
            if (tradeLog != null)
            {
                //创建交易请求对象
                Tx1320Request tx1320Request = new Tx1320Request();
                tx1320Request.setInstitutionID(institutionID);
                tx1320Request.setPaymentNo(tradeLog.SerialNumber);

                //执行报文处理
                tx1320Request.process();

                // 与支付平台进行通讯
                TxMessenger txMessenger = new TxMessenger();
                String[] respMsg = txMessenger.send(tx1320Request.getRequestMessage(), tx1320Request.getRequestSignature());

                Tx1320Response tx1320Response = new Tx1320Response(respMsg[0], respMsg[1]);
                if ("2000".Equals(tx1320Response.getCode()))
                {
                    //处理业务
                    //tx1320Response.getPaymentNo();
                    Amount = tx1320Response.getAmount();
                    //tx1320Response.getRemark();
                    //tx1320Response.getStatus();
                    NotificationTime = tx1320Response.getBankNotificationTime();
                    flag = true;
                }
            }
        }
        return flag;
    }

    /// <summary>
    /// 订单查询
    /// </summary>
    /// <param name="orderID">订单ID</param>
    /// <param name="orderPaymentList">支付记录</param>
    /// <param name="orderSettlementList">结算记录</param>
    /// <returns></returns>
    public bool OrderQuery(long orderID, string OrderNO, out ArrayList orderPaymentList, out ArrayList orderSettlementList)
    {
        orderPaymentList = null;
        orderSettlementList = null;
        bool flag = false;

        if (orderID>0)
        {
            //创建交易请求对象
            Tx1330Request tx1330Request = new Tx1330Request();
            tx1330Request.setInstitutionID(institutionID);
            tx1330Request.setOrderNo(OrderNO);

            //执行报文处理
            tx1330Request.process();

            // 与支付平台进行通讯
            TxMessenger txMessenger = new TxMessenger();
            String[] respMsg = txMessenger.send(tx1330Request.getRequestMessage(), tx1330Request.getRequestSignature());

            Tx1330Response tx1330Response = new Tx1330Response(respMsg[0], respMsg[1]);
            if ("2000".Equals(tx1330Response.getCode()))
            {
                //处理业务                    
                orderPaymentList = tx1330Response.getOrderPaymentList();
                orderSettlementList = tx1330Response.getOrderSettlementList();
                //foreach (OrderPayment op in orderPaymentList)
                //{
                //}
                flag = true;
            }
        }
        return flag;
    }
}
